1 /*
2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021
3 License:   [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License].
4 Authors: Marcelo S. N. Mancini
5 
6 	Copyright Marcelo S. N. Mancini 2018 - 2021.
7 Distributed under the CC BY-4.0 License.
8    (See accompanying file LICENSE.txt or copy at
9 	https://creativecommons.org/licenses/by/4.0/
10 */
11 
12 module hip.graphics.material;
13 import hip.math.matrix;
14 import hip.math.vector;
15 import hip.error.handler;
16 import hip.hiprenderer.shader;
17 import hip.hiprenderer.shader.shadervar;
18 
19 class Material
20 {
21     ShaderVar[string] variables;
22     Shader shader;
23     this(Shader s)
24     {
25         this.shader = s;
26     }
27 
28     void setVertexVar(T)(string varName, T data){setVar(ShaderTypes.VERTEX, varName, data);}
29     void setFragmentVar(T)(string varName, T data){setVar(ShaderTypes.FRAGMENT, varName, data);}
30     alias setPixelVar = setFragmentVar;
31     void setGeometryVar(T)(string varName, T data){setVar(ShaderTypes.GEOMETRY, varName, data);}
32 
33 
34 
35 
36     void setVar(ShaderTypes t, string varName, bool data){setVar(t, varName, &data, UniformType.boolean, data.sizeof);}
37     void setVar(ShaderTypes t, string varName, int data){setVar(t, varName, &data, UniformType.integer, data.sizeof);}
38     void setVar(ShaderTypes t, string varName, uint data){setVar(t, varName, &data, UniformType.uinteger, data.sizeof);}
39     void setVar(ShaderTypes t, string varName, float data){setVar(t, varName, &data, UniformType.floating, data.sizeof);}
40     void setVar(ShaderTypes t, string varName, float[2] data){setVar(t, varName, &data, UniformType.floating2, data.sizeof);}
41     void setVar(ShaderTypes t, string varName, float[3] data){setVar(t, varName, &data, UniformType.floating3, data.sizeof);}
42     void setVar(ShaderTypes t, string varName, float[4] data){setVar(t, varName, &data, UniformType.floating4, data.sizeof);}
43     void setVar(ShaderTypes t, string varName, float[9] data){setVar(t, varName, &data, UniformType.floating3x3, data.sizeof);}
44     void setVar(ShaderTypes t, string varName, float[16] data){setVar(t, varName, &data, UniformType.floating4x4, data.sizeof);}
45     void setVar(ShaderTypes t, string varName, Vector2 data){setVar(t, varName, &data, UniformType.floating2, data.sizeof);}
46     void setVar(ShaderTypes t, string varName, Vector3 data){setVar(t, varName, &data, UniformType.floating3, data.sizeof);}
47     void setVar(ShaderTypes t, string varName, Vector4 data){setVar(t, varName, &data, UniformType.floating4, data.sizeof);}
48     void setVar(ShaderTypes t, string varName, Matrix3 data){setVar(t, varName, &data, UniformType.floating3x3, data.sizeof);}
49     void setVar(ShaderTypes t, string varName, Matrix4 data){setVar(t, varName, &data, UniformType.floating4x4, data.sizeof);}
50 
51     protected void setVar(ShaderTypes t, string varName, void* varData, UniformType type, size_t varSize)
52     {
53         import core.stdc.string : memcpy;
54         ShaderVar* variable = (varName in variables);
55         if(variable is null)
56         {
57             ShaderVar s;
58             s.data = new void[varSize];
59             s.name = varName;
60             s.shaderType = t;
61             s.type = type;
62             variables[varName] = s;
63             variable = (varName in variables);
64         }
65         memcpy(variable.data.ptr, varData, variable.varSize);
66     }
67 
68     protected void setShaderVar(ref ShaderVar v)
69     {
70         switch(v.shaderType) with(ShaderTypes)
71         {
72             case FRAGMENT:
73                 mixin(getSetShaderVarCall("Fragment"));
74                 break;
75             case VERTEX:
76                 mixin(getSetShaderVarCall("Vertex"));
77                 break;
78             case GEOMETRY:
79             default:
80                 break;
81         }
82     }
83 
84     void bind()
85     {
86         shader.bind();
87         foreach(ref ShaderVar v; variables)
88             setShaderVar(v);
89     }
90 }
91 
92 private string getSetShaderVarCall(string shaderT)
93 {
94     import hip.util.string : replaceAll;
95     return q{
96     final switch(v.type) with(UniformType)
97     {
98         case boolean:
99             shader.set$Var(v.name, *cast(bool*)v.data);
100             break;
101         case integer:
102             shader.set$Var(v.name, *cast(int*)v.data);
103             break;
104         case integer_array:
105             shader.set$Var(v.name, *cast(int[]*)v.data);
106             break;
107         case uinteger:
108             shader.set$Var(v.name, *cast(uint*)v.data);
109             break;
110         case uinteger_array:
111             shader.set$Var(v.name, *cast(uint[]*)v.data);
112             break;
113         case floating:
114             shader.set$Var(v.name, *cast(float*)v.data);
115             break;
116         case floating2:
117             shader.set$Var(v.name, *cast(float[2]*)v.data);
118             break;
119         case floating3:
120             shader.set$Var(v.name, *cast(float[3]*)v.data);
121             break;
122         case floating4:
123             shader.set$Var(v.name, *cast(float[4]*)v.data);
124             break;
125         case floating2x2:
126             break;
127         case floating3x3:
128             shader.set$Var(v.name, *cast(Matrix3*)v.data);
129             break;
130         case floating4x4:
131             shader.set$Var(v.name, *cast(Matrix4*)v.data);
132             break;
133         case floating_array:
134             shader.set$Var(v.name, *cast(float[]*)v.data);
135             break;
136         case texture_array:
137             break;
138         case none:
139             ErrorHandler.assertExit(false, "Can't set ShaderVar of type 'none'");
140     }}.replaceAll('$', shaderT);
141 }